using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace RapidHDL
{
    public partial class MicroTrace : UserControl
    {
        Dictionary<int, int> dicAddressToLine = new Dictionary<int,int>();
        List<int> lBreakpoints;
        List<string> lOpCodes;

        string sSelectedText;

        public MicroTrace()
        {
            InitializeComponent();
        }

        public void SetProgramData(string psText, Dictionary<int, int> pdicAddressToLine, List<int> plBreakpoints, List<string> plOpCodes)
        {
            rtbText.Text = psText;
            dicAddressToLine = pdicAddressToLine;
            lBreakpoints = plBreakpoints;
            lOpCodes = plOpCodes;            
            ColorKeyWord("BREAK", Color.Red);
            ColorKeyWord("NOP", Color.Blue);
            foreach (string sOpCode in lOpCodes)
            {
                ColorKeyWord(sOpCode, Color.Blue);
            }
            GreenComments();
        }

        public string SetAddress(int piAddress)
        {
            if (dicAddressToLine.ContainsKey(piAddress))
            {
                int iLine = dicAddressToLine[piAddress] - 1;
                HighlightLine(iLine);
            }
            else
            {
                Unhighlight();
                iLastLine = -1;
                sSelectedText = "";
            }
            if (lBreakpoints.Contains(piAddress))
                return "BREAK";
            else 
                return sSelectedText;
        }

        int iLastLine = -1;

        public void Unhighlight()
        {
            if (iLastLine < 0)
                return;
            SelectLine(iLastLine);
            rtbText.SelectionBackColor = Color.White;
            Unselect(iLastLine);
        }

        public void Unselect(int piLine)
        {
            int iStart = rtbText.GetFirstCharIndexFromLine(piLine);
            rtbText.Select(iStart, 0);
        }

        public void SelectLine(int piLine)
        {
            int iStart = rtbText.GetFirstCharIndexFromLine(piLine);
            int iLen = rtbText.Lines[piLine].Length;
            rtbText.Select(iStart, iLen);
        }

        public void HighlightLine(int piLine)
        {
            Unhighlight();
            SelectLine(piLine);
            sSelectedText = rtbText.SelectedText;
            rtbText.SelectionBackColor = Color.Aqua;
            Unselect(piLine);
            iLastLine = piLine;

            if (piLine > 8)
            {
                SelectLine(piLine - 8);
                rtbText.ScrollToCaret();
            }
        }

        private void ColorKeyWord(string psWord, Color poColor)
        {
            int iPosition;
            int iStart = 0;
            string sSearch = psWord;

            iPosition = rtbText.Find(sSearch, iStart,RichTextBoxFinds.WholeWord);
            while (iPosition > 0)
            {
                rtbText.Select(iPosition, sSearch.Length);
                rtbText.SelectionColor = poColor;
                iStart = iPosition + 1;
                iPosition = rtbText.Find(sSearch, iStart, RichTextBoxFinds.WholeWord );
            }
        }

        public void GreenComments()
        {
            for (int iLine = 0; iLine < rtbText.Lines.Length; iLine++)
            {
                int iStart = rtbText.GetFirstCharIndexFromLine(iLine);
                int iLen = rtbText.Lines[iLine].Length;
                rtbText.Select(iStart, iLen);
                string sText = rtbText.SelectedText;
                int iPos = sText.IndexOf("*");
                int iPos2 = sText.IndexOf("//");
                if (iPos < 0)
                    iPos = iPos2;
                if (iPos > iPos2 && iPos2 >= 0)
                    iPos = iPos2;
                if (iPos >= 0)
                {
                    rtbText.Select(iPos + iStart, iLen - iPos);
                    rtbText.SelectionColor = Color.Green;
                }
            }
        }

        private void rtbText_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
